SQlite源码分析

读取内存日志

读取和写入是相互逆操作,这边只分析读操作,写操作简单介绍。

//从内存日志文件中读取数据
static int memjrnlRead(
  sqlite3_file *pJfd,    /* The journal file from which to read */ //读取文件的指针
  void *zBuf,            /* Put the results here */   //读取的结果
  int iAmt,              /* Number of bytes to read */  //读取的字节数
  sqlite_int64 iOfst     /* Begin reading at this offset */  //从该偏移量开始读取
){
  MemJournal *p = (MemJournal *)pJfd;
  u8 *zOut = zBuf;
  int nRead = iAmt;
  int iChunkOffset;
  FileChunk *pChunk;
  /* SQLite never tries to read past the end of a rollback journal file */
  assert( iOfst+iAmt<=p->endpoint.iOffset );
//开始的偏移量加上读取的字节数 >文件结尾的偏移量 即溢出,则报警
  if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
//不是从文件头或者文件尾开始读
sqlite3_int64 iOff = 0;
//总共需读取的偏移量
    for(pChunk=p->pFirst;
        ALWAYS(pChunk) && (iOff+JOURNAL_CHUNKSIZE)<=iOfst;
//# define ALWAYS(X)      (X)  偏移量未读完则继续
        pChunk=pChunk->pNext
    ){
      iOff += JOURNAL_CHUNKSIZE;
//总读取数累加
    }
  }else{
pChunk = p->readpoint.pChunk;
//设置为文件块的结尾
  }
  iChunkOffset = (int)(iOfst%JOURNAL_CHUNKSIZE);
//定义iOfst长度
  do {
int iSpace = JOURNAL_CHUNKSIZE - iChunkOffset;
//iSpace为所剩空间
int nCopy = MIN(nRead, (JOURNAL_CHUNKSIZE - iChunkOffset));
//输出最小的长度块
    memcpy(zOut, &pChunk->zChunk[iChunkOffset], nCopy);
zOut += nCopy;
//输出长度加
nRead -= iSpace;
//剩余空间减
    iChunkOffset = 0;
  } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
  p->readpoint.iOffset = iOfst+iAmt;
  p->readpoint.pChunk = pChunk;

  return SQLITE_OK;
}



//写数据到内存日志文件
static int memjrnlWrite(
  sqlite3_file *pJfd,    /* The journal file into which to write */
  const void *zBuf,      /* Take data to be written from here */
  int iAmt,              /* Number of bytes to write */
  sqlite_int64 iOfst     /* Begin writing at this offset into the file */
){
  MemJournal *p = (MemJournal *)pJfd;
  int nWrite = iAmt;
  u8 *zWrite = (u8 *)zBuf;
  /* An in-memory journal file should only ever be appended to. Random
  ** access writes are not required by sqlite.
  */
  //列表访问,不支持随机读写
  assert( iOfst==p->endpoint.iOffset );
  UNUSED_PARAMETER(iOfst);
  while( nWrite>0 ){
    FileChunk *pChunk = p->endpoint.pChunk;
    int iChunkOffset = (int)(p->endpoint.iOffset%JOURNAL_CHUNKSIZE);
    int iSpace = MIN(nWrite, JOURNAL_CHUNKSIZE - iChunkOffset);
if( iChunkOffset==0 ){
//偏移为0 需要新建一个文件块
      /* New chunk is required to extend the file. */
      FileChunk *pNew = sqlite3_malloc(sizeof(FileChunk));
      if( !pNew ){
        return SQLITE_IOERR_NOMEM;
      }
      pNew->pNext = 0;
//新建块的指针初始化
      if( pChunk ){
        assert( p->pFirst );
//文件头指针为0
        pChunk->pNext = pNew;
      }else{
        assert( !p->pFirst );
//文件头指针不为0
        p->pFirst = pNew;
      }
      p->endpoint.pChunk = pNew;
    }
memcpy(&p->endpoint.pChunk->zChunk[iChunkOffset], zWrite, iSpace);
//复制一个文件块
    zWrite += iSpace;
    nWrite -= iSpace;
    p->endpoint.iOffset += iSpace;
  }

  return SQLITE_OK;
}